package edu.dayu.demo3;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

public class GroupServer {
    private static Selector selector;

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        selector = Selector.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(6666));
        serverSocketChannel.configureBlocking(false);
        // 将serverSocketChannel 注册到 selector上 ,并绑定为接受
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true){
            if (selector.select()>0){
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    if (key.isAcceptable()){
                        SocketChannel channel = serverSocketChannel.accept();
                        channel.configureBlocking(false);
                        System.out.println(channel.getRemoteAddress()+"上线");
                        channel.register(selector,SelectionKey.OP_READ);
                    }
                    if (key.isReadable()){
                        readData(key);
                    }
                    iterator.remove();
                }
            }
        }
    }

    public static void readData(SelectionKey key){
        SocketChannel channel = null;
        try {
            // 通过key反向获取到对应channel
            channel = (SocketChannel)key.channel();

            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = channel.read(buffer);

            if (count > 0){
                String msg = new String(buffer.array());

                System.out.println("客户端的消息"+msg);

                // 向其他客户端发送消息。
                sendInfo(msg,channel);
            }
        } catch (IOException e) {
            try {
                System.out.println(channel.getRemoteAddress()+"离线了");
                key.cancel();
                channel.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }
    }

    public static  void sendInfo(String msg,SocketChannel self) throws IOException {
        System.out.println("服务器转发消息中");
        for (SelectionKey key : selector.keys()) {
            Channel targetChannel = key.channel();
            if (targetChannel instanceof SocketChannel && targetChannel != self){
                SocketChannel dest = (SocketChannel) targetChannel;
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8));
                dest.write(buffer);
            }
        }
    }
}
